package com.begamer.card.common.util.binRead;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;

import org.apache.log4j.Logger;

import com.begamer.card.common.util.ByteArray;
import com.begamer.card.log.MemLogger;

public class BinReader {
	private static final Logger logger = Logger.getLogger(BinReader.class);
	private static final Logger memlogger=MemLogger.logger;
	
	public static String RES_DIR = "WebRoot/res";//默认资源所在目录
	public static final byte CHAR_VARS_START = ';';
	public static final byte CHAR_COMMENT_START = '/';
	
	public BinReader()
	{
		RES_DIR=System.getProperty("card_server")+"res";
	}
	
	public void localRES_DIR()
	{
		RES_DIR="WebRoot/res";
	}
	
	/**
	 * 解析数据
	 * @param fileName
	 * @param clazz
	 */
	public void parseFile(String fileName,Class<? extends PropertyReader> clazz) {
		try{
			Object o = clazz.newInstance();
			((PropertyReader)o).resetData();//重置数据
			
			FileInputStream fis = new FileInputStream(new File(fileName));
			DataInputStream dis = new DataInputStream(fis);
			byte[] b = new byte[fis.available()];
			dis.readFully(b);
			//解密
			byte[] b2 = new byte[b.length];
			for(int k=0;k<b2.length;k++)
			{
				b2[k] = (byte)(~(b[k]-8) & 0xFF);
			}
			ByteArray ba =null;
//			if(clazz.equals(ResManagerData.class))
//			{
//				ba = new ByteArray(b);
//			}
//			else
//			{
				ba = new ByteArray(b2);
//			}
			int rows = ba.readInt();
			int cols = ba.readInt();
			Field[] fields = null;
			for(int i=0;i<rows;i++){
				String[] strs = new String[cols];
				for(int j=0;j<cols;j++){
					strs[j] = ba.readUTF().trim();
				}
				if(strs[0].length() == 0){
					continue;
				}
				if(strs[0].charAt(0) == CHAR_COMMENT_START){
					continue;
				} else if(strs[0].charAt(0) == CHAR_VARS_START){
					fields = getFields(clazz,strs);
				} else {
					parseLine(strs,fields,clazz);
				}
			}
			fis.close();
			dis.close();
			memlogger.info("读取文件：" + fileName);
		} catch(Exception e){
			logger.debug("读取文件：" + fileName + "出错",e);
			e.printStackTrace();
		}
	}
	
	
	/**
	 * lt@2012.2.17
	 * @param filename
	 * @param clazz
	 */
	public void parseFile2(String filename,Class<? extends PropertyReader> clazz)
	{
		int i=0;
		try{
			Object o = clazz.newInstance();
			((PropertyReader)o).resetData();//重置数据
			
			FileInputStream fis = new FileInputStream(new File(filename));
			byte[] b = new byte[fis.available()];
			fis.read(b);
			fis.close();
			//解密
			byte[] b2 = new byte[b.length];
			for(int k=0;k<b2.length;k++)
			{
				b2[k] = (byte)(~(b[k]-8) & 0xFF);
			}
			
			//ByteArray ba = new ByteArray(b);
			ByteArray ba = new ByteArray(b2);
			int rows = ba.readInt();
			int cols = ba.readInt();
			for(;i<rows;i++){
				String[] strs = new String[cols];
				for(int j=0;j<cols;j++){
					strs[j] = ba.readUTF();
				}
				if(strs[0].trim().length()==0){
					break;
				}else if(strs[0].charAt(0) == CHAR_COMMENT_START){
					continue;
				} else if(strs[0].charAt(0) == CHAR_VARS_START){
					continue;
				} else {
					((PropertyReader)clazz.newInstance()).parse(strs);
				}
			}
			memlogger.info("读取文件：" + filename);
		} catch(Exception e){
			logger.error("i="+i);
			logger.error("读取数据文件" + filename + "出错：", e);
		}
	}
	
	/**
	 * 解析一行
	 * @param value
	 * @param fields
	 * @param clazz
	 * @throws Exception
	 */
	protected void parseLine(String[] value,Field[] fields,Class<? extends PropertyReader> clazz) throws Exception{
		Object o = clazz.newInstance();
		for(int i=0;i<fields.length;i++){
			Field f = fields[i];
			if(f == null){
				continue;
			} 
			if(f.getType().equals(int.class)){
				f.setInt(o,decodeInt(value[i]));
			} else if(f.getType().equals(double.class)) {
				f.setDouble(o,decodeDouble(value[i]));
			} else if(f.getType().equals(int[].class)){
				f.set(o,parseIntArray(value,i));
			} else if(f.getType().equals(double[].class)){
				double[] r = new double[value.length-i];
				for(int j=0;j<r.length;j++){
					r[j] = decodeDouble(value[i+j]);
				}
				f.set(o,r);
			} else if(f.getType().equals(String[].class)){
				f.set(o,parseStringArray(value,i));
			} else if(f.getType().equals(long.class)){
				f.setLong(o, decodeLong(value[i]));
			}else if(f.getType().equals(float.class))
			{
				f.setFloat(o, decodeFloat(value[i]));
			}
			else{
				f.set(o,value[i]);
			}
		}
		((PropertyReader)o).addData();
	}
	
	/**
	 * 将字符串数组从指定索引转化成字符串数组
	 * 字符串数组将不包含指定索引
	 * @param value
	 * @param startIndex
	 * @return
	 */
	protected String[] parseStringArray(String[] value,int startIndex){
		String[] r = new String[value.length-startIndex];
		System.arraycopy(value, startIndex, r, 0, r.length);
		
		int len = 0;
		for(int i=0;i<r.length;i++){
			if(r[i].length() > 0){
				len ++;
			}
		}
		if(len == r.length){
			return r;
		} else {
			String[] d = new String[len];
			for(int i=0,j=0;i<r.length;i++){
				if(r[i].length() > 0){
					d[j] = r[i];
					j++;
				}
			}
			return d;
		}
	}
	
	
	/**
	 * 将字符串数组从指定索引转化成int数组
	 * int数组将不包含指定索引
	 * @param value
	 * @param startIndex
	 * @return
	 */
	protected int[] parseIntArray(String[] value,int startIndex){
		int[] r = new int[value.length-startIndex];
		int length = 0;
		for(int j=0;j<r.length;j++){
			r[j] = decodeInt(value[startIndex+j]);
			if(r[j] != 0){
				length++;
			}
		}
		if(length == r.length){
			return r;
		} else {
			//去0操作
			int[] d = new int[length];
			for(int i=0,j=0;i<r.length;i++){
				if(r[i] != 0){
					d[j] = r[i];
					j++;
				}
			}
			return d;
		}
	}
	
	/**
	 * 将字符串转化成数字
	 * @param str
	 * @return
	 */
	protected double decodeDouble(String str){
		try{
			return Double.parseDouble(str);
		} catch(Exception e){
			return 0;
		}
	}
	
	/**
	 * 将字符串转化成数字
	 * @param str
	 * @return
	 */
	protected int decodeInt(String str){
		try{
			return Integer.decode(str);
		} catch(Exception e){
			return 0;
		}
	}
	
	/**
	 * 将字符串转化成数字
	 * @param str
	 * @return
	 */
	protected long decodeLong(String str){
		try{
			return Long.decode(str);
		} catch(Exception e){
			return 0;
		}
	}
	
	protected float decodeFloat(String str){
		try{
			return Float.valueOf(str);
		} catch(Exception e){
			return 0;
		}
	}
	
	/**
	 * 根据变量名的字符串取得变量对象
	 * @param clazz
	 * @param strs
	 * @return
	 * @throws Exception
	 */
	protected Field[] getFields(Class<? extends PropertyReader> clazz,String[] strs) throws Exception{
		Field[] fields = new Field[strs.length];
		for(int i=0;i<strs.length;i++){
			String s = strs[i];
			if(s.length() > 0){
				if(s.charAt(0) == CHAR_VARS_START){
					s = s.substring(1,s.length());
				}
				fields[i] = clazz.getDeclaredField(s);
				fields[i].setAccessible(true);
			}
		}
		return fields;
	}
	
	/**
	 * 读所有文件
	 */
	public void readAllData(){
		//加载数据
		parseFile(RES_DIR+"/player.bin", PlayerData.class);//玩家数据
		parseFile(RES_DIR+"/newplayer.bin", NewPlayerData.class);//初始玩家数据
		parseFile(RES_DIR+"/card.bin", CardData.class);//卡牌数据
		parseFile(RES_DIR+"/cardproperty.bin", CardPropertyData.class);//卡牌属性数据
		parseFile(RES_DIR + "/energy.bin", EnergyData.class);//怒气
		parseFile(RES_DIR + "/equip.bin", EquipData.class);//装备
		parseFile(RES_DIR + "/passiveskill.bin", PassiveSkillData.class);//被动技能
		parseFile(RES_DIR + "/skill.bin", SkillData.class);//主动技能
		parseFile(RES_DIR + "/uniteskill.bin", UnitSkillData.class);//合体技
		parseFile(RES_DIR + "/items.bin", ItemsData.class);//掉落物品数据
		parseFile(RES_DIR + "/skillbasicexp.bin", SkillBasicExpData.class);//skill强化数据
		parseFile(RES_DIR + "/passiveskillbasicexp.bin", PassiveSkillBasicExpData.class);//pskill强化数据
		parseFile(RES_DIR + "/equipupgrade.bin", EquipupGradeData.class);//装备强化数据
		parseFile(RES_DIR + "/paycoe.bin", PayCoeData.class);//抽卡付费数据
		parseFile(RES_DIR + "/cardbox.bin", CardBoxData.class);//抽卡卡库数据
		parseFile(RES_DIR + "/talent.bin", TalentData.class);//天赋数据
		parseFile(RES_DIR + "/mazeskilldrop.bin", MazeSkillDropData.class);//迷宫掉落技能
		parseFile(RES_DIR + "/rune.bin", RuneData.class);//符文数据
		parseFile(RES_DIR + "/runetotal.bin", RuneTotalData.class);//符文数据
		parseFile(RES_DIR + "/imaginationdrop.bin", ImaginationdropData.class);//冥想NPC掉落道具数据
		parseFile(RES_DIR + "/carddrop.bin", CardDropData.class);//mission卡牌掉落几率数据
		parseFile(RES_DIR +"/imaginationcompose.bin", ImaginationcomposeData.class);//冥想兑换数据
		parseFile(RES_DIR +"/unlock.bin", UnLockData.class);//解锁模块
		parseFile(RES_DIR +"/taskdata.bin", TaskData.class);//剧情
		parseFile(RES_DIR +"/allthreestar.bin", AllThreeStarData.class);//3星奖励
		parseFile(RES_DIR +"/skillexp.bin", SkillExpData.class);//技能经验
		parseFile(RES_DIR +"/skillproperty.bin", SkillPropertyData.class);//技能属性
		parseFile(RES_DIR +"/power.bin", PowerData.class);//战斗力
		parseFile(RES_DIR +"/dayly.bin", DaylyData.class);//签到
		parseFile(RES_DIR +"/evolution.bin", EvolutionData.class);//突破
		parseFile(RES_DIR +"/energyup.bin", EnergyupData.class);//购买怒气
		parseFile(RES_DIR +"/uniteskillrobot.bin", UniteskillrobotData.class);//初始机器人
		parseFile(RES_DIR +"/iconUnlock.bin", IconUnlockData.class);//头像解锁
		parseFile(RES_DIR +"/changenamecost.bin", ChangeNameCostData.class);//改名花费
		parseFile(RES_DIR +"/goldcost.bin", GoldCostData.class);//购买金币
		parseFile(RES_DIR +"/spiritshop.bin", SpiritShopData.class);//购买体力
		parseFile(RES_DIR +"/pvpcdcost.bin", PvpCdCostData.class);//pvp冷却时间购买
		parseFile(RES_DIR +"/vip.bin", VipData.class);//vip相关数据
		parseFile(RES_DIR +"/missioncost.bin", MissionCostData.class);//关卡相关购买花费
		parseFile(RES_DIR +"/friendodd.bin", FriendOddData.class);//邀请好友战斗花费
		parseFile(RES_DIR +"/recharge.bin",  RechargeData.class);
		parseFile(RES_DIR +"/mazecost.bin", MazeCostData.class);
		parseFile(RES_DIR +"/friendcost.bin", FriendCostData.class);
		parseFile(RES_DIR +"/bagcost.bin", BagCostData.class);
		parseFile(RES_DIR + "/koaward.bin", KoAwardData.class);//ko积分兑换
		parseFile(RES_DIR + "/rankrobot.bin", RankRobotData.class);//排行榜机器人
		parseFile(RES_DIR + "/shop.bin", ShopData.class);
		parseFile(RES_DIR + "/blackmarket.bin", BlackMarketData.class);
		parseFile(RES_DIR + "/blackrefresh.bin", BlackRefreshData.class);
		parseFile(RES_DIR + "/blackshopbox.bin", BlackShopBoxData.class);
		parseFile(RES_DIR + "/gamebox.bin" ,GameBoxData.class);
		parseFile(RES_DIR + "/sensitivewords.bin", SensitivewordsData.class);
		parseFile(RES_DIR + "/bloodbuff.bin", BloodBuffData.class);
		parseFile(RES_DIR + "/bloodcost.bin", BloodCostData.class);
		parseFile(RES_DIR + "/wishing.bin", WishingData.class);
		parseFile(RES_DIR + "/run.bin", RunData.class);//转盘转动次数获得物品
		parseFile(RES_DIR + "/shoppvp.bin", ShoppvpData.class);
		parseFile(RES_DIR + "/cardku.bin", CardkuData.class);
		parseFile(RES_DIR + "/takecardtime.bin", TakeCardTimeData.class);
		parseFile(RES_DIR + "/bloodvalue.bin", BloodValueData.class);
		
		//================第二种加载方式===========================================================================//
		parseFile2(RES_DIR + "/equipproperty.bin", EquippropertyData.class);//装备属性
		parseFile2(RES_DIR + "/cardexp.bin", CardExpData.class);//卡牌升级经验数据
		parseFile2(RES_DIR + "/break.bin", BreakData.class);//卡牌突破数据
		parseFile2(RES_DIR + "/mission.bin", MissionData.class);//关卡数据
		parseFile2(RES_DIR + "/cardget.bin", CardGetData.class);//抽卡数据
		parseFile2(RES_DIR + "/compose.bin", ComposeData.class);//合成数据
		parseFile2(RES_DIR + "/maze.bin", MazeData.class);//迷宫数据
		parseFile2(RES_DIR + "/mazeprobability.bin", MazeProbabilityData.class);//迷宫战斗随机掉落技能类型
		parseFile2(RES_DIR + "/mazebattle.bin", MazeBattleData.class);//迷宫战斗
		parseFile2(RES_DIR + "/imagination.bin", ImaginationData.class);//冥想数据
		parseFile2(RES_DIR + "/FBevent.bin", FBeventData.class);//副本数据
		parseFile2(RES_DIR + "/event.bin", EventData.class);//活动数据
		parseFile2(RES_DIR + "/achievement.bin", AchievementData.class);//成就
		parseFile2(RES_DIR + "/firstbattle.bin", FirstBattleData.class);//新手第一次战斗
		parseFile2(RES_DIR + "/rank.bin", RankData.class);//pk排名奖励
		parseFile2(RES_DIR + "/daylytask.bin", DailyTaskData.class);//每日任务
		parseFile2(RES_DIR + "/gift.bin", GiftData.class);//在线礼包
		parseFile2(RES_DIR + "/racepower.bin", RacePowerData.class);//种族属性加成
		parseFile2(RES_DIR + "/vipgift.bin", VipGiftData.class);//vip礼包
		parseFile2(RES_DIR + "/usableitem.bin", UseableItemData.class);//消耗品
		parseFile2(RES_DIR + "/sevendays.bin", SevenDaysData.class);//七日有礼
		parseFile2(RES_DIR + "/sack.bin", SackData.class);//宝物袋
		parseFile2(RES_DIR + "/cornucopia.bin", CornucopiaData.class);//宝物袋
		parseFile2(RES_DIR + "/levelgift.bin", LevelGiftData.class);//等级奖励
		parseFile2(RES_DIR + "/vitality.bin", VitalityData.class);//活跃度礼包
		parseFile2(RES_DIR + "/mazereward.bin", MazeRewardData.class);
		parseFile2(RES_DIR + "/integralfirst.bin", IntegralFirstData.class);
		parseFile2(RES_DIR + "/runner.bin", RunnerData.class);//转盘物品
		parseFile2(RES_DIR + "/meditation.bin", MeditationData.class);//冥想任务
	}
	
	public static void main(String[] args){
		BinReader reader = new BinReader();	
		reader.readAllData();
	}
	
}